home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / demos / demobook / Index.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  17.1 KB  |  567 lines

  1. /*
  2.  * Copyright (C) 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <Xm/Xm.h>
  20. #include <X11/StringDefs.h>
  21. #include <Xm/Form.h>
  22. #include <Xm/SeparatoG.h>
  23. #include <Xm/List.h>
  24. #include <Xm/PushB.h>
  25. #include <Xm/Label.h>
  26. #include "exbookglo.h"
  27. #include "exinterfmotif.h"
  28. #include "exglobals.h"
  29.  
  30. extern char *(extract_first_xms_segment() );
  31. extern struct indexlist *(find_keyword_int() );
  32.  
  33.    Widget Index_shell;
  34.    Widget IndexList;
  35.    Widget IndexLabel1, IndexLabel2;
  36.    Widget IndexList1, IndexList2;
  37.  
  38. void browseCB_Index(Widget w, XtPointer client_data, XtPointer call_data);
  39. void doneCB_Index(Widget w, XtPointer client_data, XtPointer call_data);
  40. void make_demo_list(Widget w, struct grptmpltstruct *grpptr);
  41. void make_keyword_list(Widget w, struct wordlist *keywords);
  42. void make_book_list(Widget w, struct icntmpltstruct *icnptr);
  43. void make_empty_list(Widget w);
  44. void make_list_of_demos(Widget w, struct indexlist *ndxptr);
  45. void make_list_of_groups(Widget w, struct indexlist *ndxptr);
  46.  
  47. Widget create_Index()
  48. {
  49.    Widget form, topform;
  50.    Widget label, label1;
  51.    Widget sep, form2, bottom_sep, done_button;
  52.    Arg wargs[15];
  53.    int n;
  54.    XmStringCharSet charset = (XmStringCharSet) XmSTRING_DEFAULT_CHARSET;
  55.  
  56.    Indexwin = -1;
  57.    Index_shell = XtVaCreatePopupShell( "Indexshell",
  58.     topLevelShellWidgetClass, DBtoplevel,
  59.     XmNtitle, "Index", 
  60.     XmNallowShellResize, TRUE, NULL);
  61.  
  62.    n = 0;
  63.    XtSetArg (wargs[n], XmNverticalSpacing, 10); n++;
  64.    XtSetArg (wargs[n], XmNhorizontalSpacing, 10); n++;
  65.    topform = XtCreateManagedWidget("IndexTopForm", xmFormWidgetClass, 
  66.     Index_shell, wargs, n);
  67.  
  68.    n = 0;
  69.    XtSetArg (wargs[n], XmNallowOverlap, FALSE); n++;
  70.    XtSetArg (wargs[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  71.    XtSetArg (wargs[n], XmNleftAttachment, XmATTACH_FORM); n++;
  72.    XtSetArg (wargs[n], XmNrightAttachment, XmATTACH_FORM); n++;
  73.    form2 = XtCreateManagedWidget( "IndexForm2", xmFormWidgetClass,
  74.     topform, wargs, n);
  75.  
  76.    n = 0;
  77.    XtSetArg (wargs[n], XmNverticalSpacing, 10); n++;
  78.    XtSetArg (wargs[n], XmNleftAttachment, XmATTACH_FORM); n++;
  79.    XtSetArg (wargs[n], XmNrightAttachment, XmATTACH_FORM); n++;
  80.    XtSetArg (wargs[n], XmNtopAttachment, XmATTACH_FORM); n++;
  81.    bottom_sep = XtCreateManagedWidget("Sep", xmSeparatorGadgetClass,
  82.     form2, wargs, n);
  83.  
  84.    n = 0;
  85.    XtSetArg (wargs[n], XmNtopOffset, 10); n++;
  86.    XtSetArg (wargs[n], XmNbottomOffset, 10); n++;
  87.    XtSetArg (wargs[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  88.    XtSetArg (wargs[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  89.    XtSetArg (wargs[n], XmNtopWidget, bottom_sep); n++;
  90.    XtSetArg (wargs[n], XmNrightAttachment, XmATTACH_FORM); n++;
  91.    done_button = XtCreateManagedWidget( "DoneButton", xmPushButtonWidgetClass,
  92.     form2, wargs, n);
  93.    XtAddCallback( done_button, XmNactivateCallback, doneCB_Index, NULL);
  94.  
  95.    n = 0;
  96.    XtSetArg (wargs[n], XmNverticalSpacing, 10); n++;
  97.    XtSetArg (wargs[n], XmNhorizontalSpacing, 25); n++;
  98.    XtSetArg (wargs[n], XmNtopAttachment, XmATTACH_FORM); n++;
  99.    XtSetArg (wargs[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
  100.    XtSetArg (wargs[n], XmNbottomWidget, form2); n++;
  101.    form = XtCreateManagedWidget( "IndexForm", xmFormWidgetClass,
  102.     topform, wargs, n);
  103.  
  104.    n = 0;
  105.    XtSetArg (wargs[n], XmNalignment, XmALIGNMENT_CENTER); n++;
  106.    XtSetArg (wargs[n], XmNtopAttachment, XmATTACH_FORM); n++;
  107.    XtSetArg (wargs[n], XmNtopOffset, 15); n++;
  108.    XtSetArg (wargs[n], XmNrightAttachment, XmATTACH_FORM); n++;
  109.    XtSetArg (wargs[n], XmNleftAttachment, XmATTACH_FORM); n++;
  110.    label = XtCreateManagedWidget("IndexLabel", xmLabelWidgetClass,
  111.     form, wargs, n);
  112.  
  113.    n = 0;
  114.    XtSetArg (wargs[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  115.    XtSetArg (wargs[n], XmNbottomOffset, 15); n++;
  116.    XtSetArg (wargs[n], XmNrightAttachment, XmATTACH_FORM); n++;
  117.    XtSetArg (wargs[n], XmNleftAttachment, XmATTACH_FORM); n++;
  118.    XtSetArg (wargs[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
  119.    XtSetArg (wargs[n], XmNborderWidth, 1); n++;
  120.  
  121. /*   XtSetArg (wargs[n], XmNlabelString,
  122.       XmStringCreateLtoR("Legend:\nK    Keyword\nD    Demo Name\nB    Book Name", charset)); n++; */
  123.  
  124.    label1 = XtCreateManagedWidget("LegendLabel", xmLabelWidgetClass,
  125.     form, wargs, n);
  126.  
  127.    n = 0;
  128.    XtSetArg (wargs[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  129.    XtSetArg (wargs[n], XmNtopWidget, label); n++;
  130.    XtSetArg (wargs[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
  131.    XtSetArg (wargs[n], XmNbottomWidget, label1); n++;
  132.    XtSetArg (wargs[n], XmNrightAttachment, XmATTACH_FORM); n++;
  133.    XtSetArg (wargs[n], XmNleftAttachment, XmATTACH_FORM); n++;
  134.    IndexList = XmCreateScrolledList(form, "IndexList", wargs, n);
  135.  
  136.    XtManageChild(IndexList);
  137.    XtAddCallback( IndexList, XmNbrowseSelectionCallback, browseCB_Index, NULL);
  138.  
  139.    n = 0;
  140.    XtSetArg (wargs[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
  141.    XtSetArg (wargs[n], XmNbottomWidget, form2); n++;
  142.    XtSetArg (wargs[n], XmNtopAttachment, XmATTACH_FORM); n++;
  143.    XtSetArg (wargs[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
  144.    XtSetArg (wargs[n], XmNleftWidget, form); n++;
  145.    XtSetArg (wargs[n], XmNorientation, XmVERTICAL); n++;
  146.    sep = XtCreateManagedWidget("Sep", xmSeparatorGadgetClass,
  147.     topform, wargs, n);
  148.  
  149.    n = 0;
  150.    XtSetArg (wargs[n], XmNtopAttachment, XmATTACH_FORM); n++;
  151.    XtSetArg (wargs[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
  152.    XtSetArg (wargs[n], XmNleftWidget, sep); n++;
  153.    XtSetArg (wargs[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
  154.    XtSetArg (wargs[n], XmNbottomWidget, form2); n++;
  155.    XtSetArg (wargs[n], XmNverticalSpacing, 5); n++;
  156.    XtSetArg (wargs[n], XmNhorizontalSpacing, 25); n++;
  157.    form = XtCreateManagedWidget( "IndexForm", xmFormWidgetClass,
  158.     topform, wargs, n);
  159.  
  160.    n = 0;
  161.    XtSetArg (wargs[n], XmNtopOffset, 42); n++;
  162.    XtSetArg (wargs[n], XmNtopAttachment, XmATTACH_FORM); n++;
  163.    XtSetArg (wargs[n], XmNrightAttachment, XmATTACH_FORM); n++;
  164.    XtSetArg (wargs[n], XmNleftAttachment, XmATTACH_FORM); n++;
  165.    XtSetArg (wargs[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
  166.    XtSetArg (wargs[n], XmNlabelString,
  167.     XmStringCreateLtoR("    ", charset)); n++;
  168.    IndexLabel1 = XtCreateManagedWidget("IndexLabel1", xmLabelWidgetClass,
  169.     form, wargs, n);
  170.  
  171.    n = 0;
  172.    XtSetArg (wargs[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  173.    XtSetArg (wargs[n], XmNtopWidget, IndexLabel1); n++;
  174.    XtSetArg (wargs[n], XmNrightAttachment, XmATTACH_FORM); n++;
  175.    XtSetArg (wargs[n], XmNleftAttachment, XmATTACH_FORM); n++;
  176.    XtSetArg (wargs[n], XmNvisibleItemCount, 5); n++;
  177.    IndexList1 = XmCreateScrolledList(form, "IndexList1", wargs, n);
  178.    XtManageChild(IndexList1);
  179.  
  180.    n = 0;
  181.    XtSetArg (wargs[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  182.    XtSetArg (wargs[n], XmNtopWidget, IndexList1); n++;
  183.    XtSetArg (wargs[n], XmNtopOffset, 25); n++;
  184.    XtSetArg (wargs[n], XmNrightAttachment, XmATTACH_FORM); n++;
  185.    XtSetArg (wargs[n], XmNleftAttachment, XmATTACH_FORM); n++;
  186.    XtSetArg (wargs[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
  187.    XtSetArg (wargs[n], XmNlabelString,
  188.     XmStringCreateLtoR("    ", charset)); n++;
  189.    IndexLabel2 = XtCreateManagedWidget("IndexLabel2", xmLabelWidgetClass,
  190.     form, wargs, n);
  191.  
  192.    n = 0;
  193.    XtSetArg (wargs[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  194.    XtSetArg (wargs[n], XmNtopWidget, IndexLabel2); n++;
  195.    XtSetArg (wargs[n], XmNrightAttachment, XmATTACH_FORM); n++;
  196.    XtSetArg (wargs[n], XmNleftAttachment, XmATTACH_FORM); n++;
  197.    XtSetArg (wargs[n], XmNvisibleItemCount, 5); n++;
  198.    IndexList2 = XmCreateScrolledList(form, "IndexList2", wargs, n);
  199.    XtManageChild(IndexList2);
  200.  
  201.    XtRealizeWidget(Index_shell);
  202.    SetWMhints(Index_shell);
  203.    return(Index_shell);
  204. }
  205.  
  206.  
  207. #define KEYSIZE 7    /* char key + 5 spaces + comma */
  208. void update_index_win()
  209. {
  210.    static long limit;
  211.    static short nblocks = 0;
  212.    static char *list = NULL;
  213.    struct indexlist *ndxptr;
  214.    long cumlength = 0;
  215.    int count = 0;
  216.    int blocksize = 1024;
  217.    /* int i; */
  218.  
  219.    /*  Display "working" dialog message. */
  220.    sprintf(msgstring, "\nBuidling Index... Please wait\n");
  221.    UxPopupInterface(create_Working(), no_grab);
  222.    handleMotifInterfaceEvents();
  223.  
  224.    ndxptr = Index;
  225.    if (list == NULL) {
  226.     list = malloc(blocksize);
  227.        limit = (1024 * nblocks)-9;
  228.     nblocks = 1;
  229.    }
  230.    *list = '\0';
  231.    /* for (i = 0; i < blocksize; i++)
  232.       list[i] = '\0';
  233.    */
  234.    /* strcpy(list, ""); */
  235.    while (ndxptr != NULL)
  236.       {
  237.  
  238. #ifdef DEBUG
  239.       fprintf(stderr,"%s\n",ndxptr->string);
  240. #endif
  241.  
  242.       count++;
  243.       cumlength+=(strlen(ndxptr->string)+KEYSIZE);
  244.       if (cumlength > limit)
  245.          {
  246.          nblocks++;
  247.          list = (char *)realloc((void *)list, 1024*(nblocks));
  248.          limit = (1024 * nblocks) - 1;
  249.          }
  250.       if (ndxptr->icon != NULL)
  251.          strcat(list, "D     ");
  252.       else if (ndxptr->group != NULL)
  253.          strcat(list, "B     ");
  254.       else
  255.          strcat(list, "K     ");
  256.       strcat(list, (ndxptr->string));
  257.       strcat(list, ",");
  258.       ndxptr = ndxptr->next;
  259.  
  260.       }
  261.  
  262.       /* strcat(list, "\0"); */
  263.  
  264. #ifdef DEBUG
  265.    fprintf(stderr,"cumlength:%d strlen(list):%d\n",cumlength,strlen(list));
  266. #endif
  267.  
  268.    XtVaSetValues( IndexList, 
  269.     XmNitemCount, count,
  270.     RES_CONVERT(XmNitems, list),
  271.     NULL);
  272. #ifdef DEBUG
  273.    fprintf(stderr,"Damn! made it past that XtVaSetGarbage call!\n");
  274. #endif
  275.  
  276.    /* Quit "working" dialog message. */
  277.    UxPopdownInterface(Working);
  278.    handleMotifInterfaceEvents();
  279.  
  280. }
  281.  
  282. void popup_Index()
  283. {
  284.    update_index_win();
  285.    Indexwin = 1;
  286.    XtPopup(Index_w, XtGrabNone);
  287. }
  288.  
  289. void doneCB_Index(Widget w, XtPointer client_data, XtPointer call_data)
  290. {
  291.    Indexwin = -1;
  292.    XtPopdown(Index_w);
  293. }
  294.  
  295. void browseCB_Index(Widget w, XtPointer client_data, XtPointer call_data)
  296. {
  297.    struct indexlist *found_word;
  298.    char *my_string;
  299.    int n;
  300.    Arg wargs[2];
  301.    XmStringCharSet charset = (XmStringCharSet) XmSTRING_DEFAULT_CHARSET;
  302.    int tmp;
  303.    XmListCallbackStruct *callstruct;
  304.  
  305.    callstruct = (XmListCallbackStruct *)call_data;
  306.    if (callstruct->reason == XmCR_BROWSE_SELECT)
  307.       {
  308.       my_string = extract_first_xms_segment(callstruct->item);
  309.       tmp = callstruct->item_position-1;
  310.       found_word = find_keyword_int(callstruct->item_position-1);
  311. /*I
  312. printf(" position %d   word %s  occur = %d\n", tmp, found_word->string,found_word->count);
  313. */
  314.       if (found_word->group != NULL)
  315.          {
  316.          n = 0;
  317.          XtSetArg (wargs[n], XmNlabelString,
  318.         XmStringCreateLtoR("Demos in this Book", charset)); n++;
  319.          XtSetValues(IndexLabel1, wargs, n); 
  320.          make_demo_list(IndexList1, found_word->group);
  321.          n = 0;
  322.          XtSetArg (wargs[n], XmNlabelString,
  323.         XmStringCreateLtoR("Keywords of the Book", charset)); n++;
  324.          XtSetValues(IndexLabel2, wargs, n); 
  325.          make_keyword_list(IndexList2, found_word->group->keywords);
  326.          }
  327.       else if (found_word->icon != NULL)
  328.          {
  329.          n = 0;
  330.          XtSetArg (wargs[n], XmNlabelString,
  331.         XmStringCreateLtoR("Keywords of this Demo", charset)); n++;
  332.          XtSetValues(IndexLabel1, wargs, n); 
  333.          make_keyword_list(IndexList1, found_word->icon->keywords);
  334.          n = 0;
  335.          XtSetArg (wargs[n], XmNlabelString,
  336.         XmStringCreateLtoR("Demo can be found in these Books", charset)); n++;
  337.          XtSetValues(IndexLabel2, wargs, n); 
  338.          make_book_list(IndexList2, found_word->icon);
  339.          }
  340.       else
  341.          {
  342.          n = 0;
  343.          XtSetArg (wargs[n], XmNlabelString,
  344.         XmStringCreateLtoR("Demos with this Keyword", charset)); n++;
  345.          XtSetValues(IndexLabel1, wargs, n); 
  346.          make_list_of_demos(IndexList1, found_word);
  347.          n = 0;
  348.          XtSetArg (wargs[n], XmNlabelString,
  349.         XmStringCreateLtoR("Books with this Keyword", charset)); n++;
  350.          XtSetValues(IndexLabel2, wargs, n); 
  351.          make_list_of_groups(IndexList2, found_word);
  352.          }
  353.       }
  354. }
  355.  
  356. void make_empty_list(Widget w)
  357. {
  358.    int count;
  359.    char *list;
  360.    int i;
  361.    int blocksize = 2;
  362.    
  363.    count = 0;
  364.    list = malloc(blocksize * sizeof(char) );
  365.    for (i = 0; i < blocksize; i++)
  366.       list[i] = '\0';
  367.  
  368.    XtVaSetValues( w, XmNitemCount, count,
  369.     RES_CONVERT(XmNitems, list),
  370.     NULL);
  371. }
  372.  
  373. void make_list_of_demos(Widget w, struct indexlist *ndxptr)
  374. {
  375.    struct iconstruct *tmpicon;
  376.    int count;
  377.    char *list;
  378.    int cumlength = 0;
  379.    int len;
  380.    int numalloc = 1;
  381.    int i;
  382.    int blocksize = 128;
  383.  
  384.    tmpicon = ndxptr->icons;
  385.    if (tmpicon == NULL)
  386.       make_empty_list(w);
  387.    else
  388.       {
  389.       count = 0;
  390.       list = malloc(blocksize * sizeof(char) );
  391.       for (i = 0; i < blocksize; i++)
  392.          list[i] = '\0';
  393.       while (tmpicon != NULL)
  394.          {
  395.          len = strlen(tmpicon->iconptr->nameptr->string);
  396.          if (len+cumlength+1 > blocksize * numalloc - 2 )
  397.             {
  398.             numalloc++;
  399.             list = realloc( (void *)list, blocksize * numalloc);
  400.             }
  401.          count++;
  402.          cumlength+=(len+1);
  403.          strcat(list, (tmpicon->iconptr->nameptr->string) );
  404.          strcat(list, ",");
  405.          tmpicon = tmpicon->nexticon;
  406.          }
  407.    XtVaSetValues( w, XmNitemCount, count,
  408.     RES_CONVERT(XmNitems, list),
  409.     NULL);
  410.       }
  411. }
  412.  
  413. void make_list_of_groups(Widget w, struct indexlist *ndxptr)
  414. {
  415.    struct grpliststruct *tmpgrpl;
  416.    int count;
  417.    char *list;
  418.    int cumlength = 0;
  419.    int len;
  420.    int numalloc = 1;
  421.    int i;
  422.    int blocksize = 128;
  423.  
  424.    tmpgrpl = ndxptr->grps;
  425.    if (tmpgrpl == NULL)
  426.       make_empty_list(w);
  427.    else
  428.       {
  429.       count = 0;
  430.       list = malloc(blocksize * sizeof(char) );
  431.       for (i = 0; i < blocksize; i++)
  432.          list[i] = '\0';
  433.       while (tmpgrpl != NULL)
  434.          {
  435.          len = strlen(tmpgrpl->grpptr->nameptr->string);
  436.          if (len+cumlength+1 > blocksize * numalloc - 2 )
  437.             {
  438.             numalloc++;
  439.             list = realloc( (void *)list, blocksize * numalloc);
  440.             }
  441.          count++;
  442.          cumlength+=(len+1);
  443.          strcat(list, (tmpgrpl->grpptr->nameptr->string) );
  444.          strcat(list, ",");
  445.          tmpgrpl = tmpgrpl->next;
  446.          }
  447.    XtVaSetValues( w, XmNitemCount, count,
  448.     RES_CONVERT(XmNitems, list),
  449.     NULL);
  450.       }
  451. }
  452.  
  453. void make_demo_list(Widget w, struct grptmpltstruct *grpptr)
  454. {
  455.    int count;
  456.    char *list;
  457.    int cumlength = 0;
  458.    int len;
  459.    int numalloc = 1;
  460.    struct pagestruct *tmppg;
  461.    struct iconstruct *tmpicon;
  462.    int i;
  463.    int blocksize = 256;
  464.  
  465.    count = 0;
  466.    list = malloc(blocksize * sizeof(char) );
  467.    for (i = 0; i < blocksize; i++)
  468.       list[i] = '\0';
  469.    tmppg = grpptr->firstpage;
  470.    while(tmppg!= NULL)
  471.       {
  472.       tmpicon = tmppg->fronticons;
  473.  /* list of demos is continuous from page to page, fron and back */
  474.       while(tmpicon != NULL)
  475.          {
  476.          len = strlen(tmpicon->iconptr->nameptr->string);
  477.          if (len+cumlength+1 > blocksize * numalloc - 2 )
  478.             {
  479.             numalloc++;
  480.             list = realloc( (void *)list, blocksize * numalloc);
  481.             }
  482.          count++;
  483.          cumlength+=(len+1);
  484.          strcat(list, (tmpicon->iconptr->nameptr->string) );
  485.          strcat(list, ",");
  486.          tmpicon = tmpicon->nexticon;
  487.          }
  488.       tmppg = tmppg->nextpage;
  489.       }
  490.    
  491.    XtVaSetValues( w, XmNitemCount, count,
  492.     RES_CONVERT(XmNitems, list),
  493.     NULL);
  494. }
  495.  
  496. void make_keyword_list(Widget w, struct wordlist *keywords)
  497. {
  498.    int count;
  499.    char *list;
  500.    int len;
  501.    int cumlength = 0;
  502.    int numalloc = 1;
  503.    struct wordlist *tmpkw;
  504.    int i;
  505.    int blocksize = 64;
  506.  
  507.    count = 0;
  508.    list = malloc(blocksize * sizeof(char) );
  509.    for (i = 0; i < blocksize; i++)
  510.       list[i] = '\0';
  511.    tmpkw = keywords;
  512.    while (tmpkw != NULL)
  513.       {
  514.       len = strlen(tmpkw->indexptr->string);
  515.       if (len+cumlength+1 > blocksize * numalloc - 2 )
  516.          {
  517.          numalloc++;
  518.          list = realloc( (void *)list, blocksize * numalloc);
  519.          }
  520.       count++;
  521.       cumlength+=(len+1);
  522.       strcat(list, (tmpkw->indexptr->string));
  523.       strcat(list, ",");
  524.       tmpkw = tmpkw->next;
  525.       }
  526.    XtVaSetValues( w, XmNitemCount, count,
  527.     RES_CONVERT(XmNitems, list),
  528.     NULL);
  529. }
  530.  
  531. void make_book_list(Widget w, struct icntmpltstruct *icnptr)
  532. {
  533.    int count;
  534.    char *list;
  535.    int len;
  536.    int cumlength = 0;
  537.    int numalloc = 1;
  538.    struct grpliststruct *tmpgrp;
  539.    int i;
  540.    int blocksize = 64;
  541.  
  542.    count = 0;
  543.    list = malloc(blocksize * sizeof(char) );
  544.    for (i = 0; i < blocksize; i++)
  545.       list[i] = '\0';
  546.    tmpgrp = icnptr->grps;
  547.    while (tmpgrp != NULL)
  548.       {
  549.       len = strlen(tmpgrp->grpptr->nameptr->string);
  550.       if (len+cumlength+1 > blocksize * numalloc - 2 )
  551.          {
  552.          numalloc++;
  553.          list = realloc( (void *)list, blocksize * numalloc);
  554.          }
  555.       count++;
  556.       cumlength+=(len+1);
  557.       strcat(list, (tmpgrp->grpptr->nameptr->string));
  558.       strcat(list, ",");
  559.       tmpgrp = tmpgrp->next;
  560.       }
  561.    XtVaSetValues( w, XmNitemCount, count,
  562.         RES_CONVERT(XmNitems, list),
  563.         NULL);
  564. }
  565.  
  566.  
  567.